<?php
namespace Icsoc\DataBundle\Model;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Icsoc\CoreBundle\Logger\ActionLogger;

/**
 * 下面中用到info参数的json格式大概为 ；filter搜素(具体提供搜素字段各个接口不一样)，
 *  pagination分页(rows 每页显示条数,page第几页)，sort排序
 *  {"pagination":{"rows":20,"page":"5"},"filter":{"endresult":"0"},"sort":{"field":"id","order":"desc"}}
 * Class BillModel
 * @package Icsoc\DataBundle\Model
 *
 */
class QueueModel extends BaseModel
{

    /** @var \Symfony\Component\DependencyInjection\Container */
    public $container;

    /** @var \Doctrine\DBAL\Connection */
    private $dbal;

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->dbal = $this->container->get('doctrine.dbal.default_connection');
    }

    /**
     * 添加技能组
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         que_name,//技能组名称
     *                         que_tag,//技能组描述
     *                         que_type,//技能组名称（0 呼入呼出 1 呼入 2呼出）
     *                         que_length,//技能组最大排队数
     *                         que_time,//技能组最大排队时长（超过此时长溢出）
     *                         ring_time,//坐席振铃时长（超过此时长转下一个坐席）
     *                         next_wait,//分配等待时长
     *                         b_announce,//是否报工号（1 是 0 否）
     *                         noans_times,//技能组无应答次数（超过此次数则溢出）
     *                         noans_wait,//坐席无应答等待时长
     *                         wait_audio,//队列等待音
     *                         noans_action,//无应答操作 （0：不处理，1：示忙,2:强退出队列）
     *                         que_strategy,//分配策略(值目前就 1 和 2 ) 1 是最长等待时间2 技能高优先
     *                     )
     * @param int   $isEnableGroup
     * @return array|bool|string
     */
    public function add(array $param = array(), $isEnableGroup = 0)
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queName = empty($param['que_name']) ? 0 : $this->purifyHtml($param['que_name']);
        $queNum = empty($param['que_num']) ? '' : $param['que_num'];
        $queTag = empty($param['que_tag']) ? 0 : $param['que_tag'];
        $queType = empty($param['que_type']) ? 0 : $param['que_type'];
        $queLength = empty($param['que_length']) ? 0 : $param['que_length'];
        $queTime = empty($param['que_time']) ? 0 : $param['que_time'];
        $ringTime = empty($param['ring_time']) ? 0 : $param['ring_time'];
        $nextWait = empty($param['next_wait']) ? 0 : $param['next_wait'];
        $bAnnounce = empty($param['b_announce']) ? 0 : $param['b_announce'];
        $noansTimes = empty($param['noans_times']) ? 0 : $param['noans_times'];
        $noansWait = empty($param['noans_wait']) ? 0 : $param['noans_wait'];
        $waitAudio = empty($param['wait_audio']) ? 0 : $param['wait_audio'];
        $noansAction = !isset($param['noans_action']) ? 1 : $param['noans_action'];
        $queStrategy = !isset($param['que_strategy']) ? 1 : $param['que_strategy'];
        $quePriority = empty($param['que_priority']) ? 1 : (int) $param['que_priority'];
        $brecord = empty($param['brecord']) ? 0 : $param['brecord'];
        $timeConfig = empty($param['que_time_config']) ? '' : $param['que_time_config'];
        //$tellevel = empty($param['tellevel']) ? 0 & ~0x20 : 0 | 0x20;
        $tellevel = empty($param['tellevel']) ? 0 & ~0x20 : 0 | 0x20;
        //$tellevel = empty($param['auto_evaluate']) ? $tellevel & ~0x40 : $tellevel | 0x40;
        $groupBelong = array();
        if (!empty($isEnableGroup)) {
            $groupBelong = empty($param['group_belong']) ? array() : $param['group_belong'];
        }

        //vcc_code 验证
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //技能组验证
        $msg = $this->container->get('icsoc_data.validator')->isEmptyName($queName);
        if (!empty($msg)) {
            return $msg;
        }

        $winIp = $this->container->get('icsoc_core.common.class')->newGetWinIp();
        //$win_ip = $user->getWinIp();
        $port = $this->container->getParameter('win_socket_port');

        //技能组名称重复
        $where = " vcc_id = :vcc_id AND que_name = :que_name AND is_del = 0";
        $parArr = array('vcc_id' => $vid, 'que_name' => $queName);
        $msg = $this->container->get('icsoc_data.validator')->existQue($where, $parArr, 404);
        if (!empty($msg)) {
            return $msg;
        }

        if (!empty($queNum)) {
            //检查技能组号是否重复
            $where = " vcc_id = :vcc_id AND que_num = :que_num AND is_del = 0";
            $parArr = array('vcc_id' => $vid, 'que_num' => $queNum);
            $msg = $this->container->get('icsoc_data.validator')->existQue($where, $parArr);
            if (!empty($msg)) {
                return array('code' => 405, 'message' => '技能组号已经存在');
            }
        }
        if (!($quePriority >= 0 && $quePriority <= 255)) {
            return array('code' => 408, 'message' => '技能组优先级的值为0-255之间数字');
        }
        //查看最大技能组数
        $ques = $this->dbal->fetchColumn(
            'SELECT groups
            FROM cc_ccods
            WHERE vcc_id = :vcc_id ',
            array('vcc_id' => $vid)
        );

        $alreay = $this->dbal->fetchColumn(
            'SELECT count(*)
            FROM win_queue
            WHERE vcc_id = :vcc_id AND is_del = 0',
            array('vcc_id' => $vid)
        );
        //0 是不限制的；
        if ($alreay >= $ques && !empty($ques) && $ques != 0) {
            $ret = array(
                'code' => 407,
                'message' => '技能组数量达到上限',
            );

            return $ret;
        }
        //默认和其它技能组一样；
        $oldTellevel = $this->dbal->fetchColumn(
            "SELECT tellevel FROM win_queue WHERE vcc_id = ? AND is_del = 0 LIMIT 1",
            array($vid)
        );
        $autoEvaluate = $oldTellevel & 64;
        $tellevel = empty($autoEvaluate) ? $tellevel & ~0x40 : $tellevel | 0x40;
        $data = array(
            'vcc_id' => $vid,
            'que_name' => $queName,
            'que_tag' => $queTag,
            'que_type' => $queType,
            'que_length' => $queLength,
            'que_time' => $queTime,
            'ring_time' => $ringTime,
            'next_wait' => $nextWait,
            'b_announce' => $bAnnounce,
            'noans_times' => $noansTimes,
            'noans_wait' => $noansWait,
            'wait_audio' => $waitAudio,
            'que_strategy' => $queStrategy,
            'brecord' => $brecord,
            'que_num' => $queNum,
            'que_priority' => $quePriority,
            'noans_action' => in_array($noansAction, array(0, 1, 2)) ? $noansAction : 1,
            'tellevel' => $tellevel,
            'group_belong' => implode(",", $groupBelong),
            'que_time_config' => $timeConfig,
        );
        try {
            $this->dbal->insert('win_queue', $data);
            //插入队列
            $queId = $this->dbal->lastInsertId();
            $mqData['que_id'] = $queId;
            $mqData['vcc_id'] = $vid;
            $mqData['que_name'] = $data['que_name'];
            $mqData['que_type'] = $data['que_type'];
            $this->writeMq(array('action' => 'create', 'data' => $mqData));
            //插入成功之后；重载技能组；
            $ret = $this->container->get('icsoc_data.validator')->wintelsReload($vid, $winIp, $port, 406);
            /** @var ActionLogger $actionLogger */
            $actionLogger = $this->container->get('icsoc_core.helper.logger');
            $logStr = $this->container->get('translator')->trans('Add queue %str%', array('%str%' => $queName));
            $actionLogger->actionLog(ActionLogger::ACTION_ADD, $logStr);

            return $ret;
        } catch (\Exception $e) {
            $ret = array(
                'code' => 409,
                'message' => '添加技能组失败['.$e->getMessage().']',
            );

            return $ret;
        }
    }

    /**
     * 修改技能组
     * @param array $param 参数，格式为
     *                     array(
     *                         que_id, //技能组id
     *                         vcc_code,//企业代码
     *                         que_name,//技能组名称
     *                         que_tag,//技能组描述
     *                         que_type,//技能组名称（0 呼入呼出 1 呼入 2呼出）
     *                         que_length,//技能组最大排队数
     *                         que_time,//技能组最大排队时长（超过此时长溢出）
     *                         ring_time,//坐席振铃时长（超过此时长转下一个坐席）
     *                         next_wait,//分配等待时长
     *                         b_announce,//是否报工号（1 是 0 否）
     *                         noans_times,//技能组无应答次数（超过此次数则溢出）
     *                         noans_wait,//坐席无应答等待时长
     *                         wait_audio,//队列等待音
     *                         noans_action,//无应答操作 （0：不处理，1：示忙,2:强退出队列）
     *                         que_strategy,//分配策略(值目前就 1 和 2 ) 1 是最长等待时间2 技能高优先
     *                         que_priority,//技能组优先级
     *                     )
     * @param int   $isEnableGroup
     * @return array|bool|string
     */
    public function update(array $param = array(), $isEnableGroup = 0)
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queName = empty($param['que_name']) ? 0 : $this->purifyHtml($param['que_name']);
        $queNum = empty($param['que_num']) ? '' : $param['que_num'];
        $quePriority = empty($param['que_priority']) ? 0 : $param['que_priority'];
        $queTag = empty($param['que_tag']) ? 0 : $param['que_tag'];
        $queType = empty($param['que_type']) ? 0 : $param['que_type'];
        $queLength = empty($param['que_length']) ? 0 : $param['que_length'];
        $queTime = empty($param['que_time']) ? 0 : $param['que_time'];
        $ringTime = empty($param['ring_time']) ? 0 : $param['ring_time'];
        $nextWait = empty($param['next_wait']) ? 0 : $param['next_wait'];
        $bAnnounce = empty($param['b_announce']) ? 0 : $param['b_announce'];
        $noansTimes = empty($param['noans_times']) ? 0 : $param['noans_times'];
        $noansWait = empty($param['noans_wait']) ? 0 : $param['noans_wait'];
        $waitAudio = empty($param['wait_audio']) ? 0 : $param['wait_audio'];
        $noansAction = !isset($param['noans_action']) ? 1 : $param['noans_action'];
        $brecord = empty($param['brecord']) ? 0 : $param['brecord'];
        $queStrategy = !isset($param['que_strategy']) ? 1 : $param['que_strategy'];
        $queId = empty($param['que_id']) ? 0 : $param['que_id'];
        $timeConfig = empty($param['que_time_config']) ? '' : $param['que_time_config'];
        //$user = $this->container->get("security.token_storage")->getToken()->getUser();
        //$winip = $this->container->getParameter("win_ip");
        $groupBelong = array();
        if (!empty($isEnableGroup)) {
            $groupBelong = empty($param['group_belong']) ? array() : $param['group_belong'];
        }

        //vcc_code 验证
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //技能组验证
        $msg = $this->container->get('icsoc_data.validator')->isEmptyName($queName);
        if (!empty($msg)) {
            return $msg;
        }

        //验证技能组id 是否属于该企业；
        $msg = $this->container->get('icsoc_data.validator')->vccQue($vid, $queId);
        if (!empty($msg)) {
            return $msg;
        }
        $winIp = $this->container->get('icsoc_core.common.class')->newGetWinIp();
        //$win_ip = $user->getWinIp();
        $port = $this->container->getParameter('win_socket_port');

        //技能组名称重复
        $where = " vcc_id = :vcc_id AND que_name = :que_name AND id <> :que_id AND is_del = 0";
        $parArr = array('vcc_id' => $vid, 'que_name' => $queName, 'que_id' => $queId);
        $msg = $this->container->get('icsoc_data.validator')->existQue($where, $parArr);
        if (!empty($msg)) {
            return $msg;
        }
        if (!empty($queNum)) {
            //检查技能组号是否重复
            $where = " vcc_id = :vcc_id AND que_num = :que_num AND is_del = 0 AND id <> :que_id";
            $parArr = array('vcc_id' => $vid, 'que_num' => $queNum, 'que_id' => $queId);
            $msg = $this->container->get('icsoc_data.validator')->existQue($where, $parArr);
            if (!empty($msg)) {
                return array('code' => 409, 'message' => '技能组号已经存在');
            }
        }
        if (!($quePriority >= 0 && $quePriority <= 255)) {
            return array('code' => 408, 'message' => '技能组优先级的值为0-255之间数字');
        }

        //开始修改入库
        $data = array(
            'que_name' => $queName,
            'que_tag' => $queTag,
            'que_type' => $queType,
            'que_length' => $queLength,
            'que_time' => $queTime,
            'ring_time' => $ringTime,
            'next_wait' => $nextWait,
            'b_announce' => $bAnnounce,
            'noans_times' => $noansTimes,
            'noans_wait' => $noansWait,
            'wait_audio' => $waitAudio,
            'que_strategy' => $queStrategy,
            'brecord' => $brecord,
            'que_num' => $queNum,
            'que_priority' => $quePriority,
            'noans_action' => in_array($noansAction, array(0, 1, 2)) ? $noansAction : 1,
            'group_belong' => implode(",", $groupBelong),
            'que_time_config' => $timeConfig,
        );
        try {
            //先查出原值；记录日志差别；
            $oldQue = $this->dbal->fetchAssoc(
                "SELECT que_name,que_tag,que_type,que_length,que_time,ring_time,next_wait,tellevel,
                b_announce,noans_times,noans_wait,wait_audio,que_strategy,brecord,noans_action,que_num,que_priority,group_belong,que_time_config
                FROM win_queue WHERE id = :id ",
                array('id' => $queId)
            );
            $logStr = '';
            $diff = array_diff_assoc($data, $oldQue);
            foreach ($diff as $k => $v) {
                $logStr .= "[".$k."]:".$oldQue[$k]."=>".$data[$k].' ';
            }

            $tellevel = empty($param['tellevel']) ? $oldQue['tellevel'] & ~0x20 : $oldQue['tellevel'] | 0x20;
            $autoEvaluate = $oldQue['tellevel'] & 64;
            $tellevel = empty($autoEvaluate) ? $tellevel & ~0x40 : $tellevel | 0x40;
            $data['tellevel'] = $tellevel;
            $this->dbal->update('win_queue', $data, array('vcc_id' => $vid, 'id' => $queId));
            //插入队列
            $Mqdata['que_id'] = $queId;
            $Mqdata['vcc_id'] = $vid;
            $Mqdata['que_name'] = $data['que_name'];
            $Mqdata['que_type'] = $data['que_type'];
            $this->writeMq(array('action'=>'update', 'data'=>$Mqdata));
            $ret = $this->container->get('icsoc_data.validator')->wintelsReload($vid, $winIp, $port, 407);
            if (!empty($logStr)) {
                /** @var ActionLogger $actionLogger */
                $actionLogger = $this->container->get('icsoc_core.helper.logger');
                $logStr = $this->container->get('translator')->trans('Update queue %str%', array('%str%' => $logStr));
                $actionLogger->actionLog(ActionLogger::ACTION_UPDATE, $logStr);
            }

            return $ret;
        } catch (\Exception $e) {
            $ret = array(
                'code' => 406,
                'message' => '编辑技能组失败['.$e->getMessage().']',
            );

            return $ret;
        }
    }


    /**
     * 删除技能组
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         que_id,//技能组id
     *                         flag,//(1代表确认，0，需要验证是否有坐席)
     *                     )
     * @return array
     */
    public function delQue(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queId = empty($param['que_id']) ? '' : $param['que_id'];
        $flag = empty($param['flag']) ? 0 : $param['flag'];
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }
        //有批量删除情况
//        $que_arr = json_decode($que_id);
//        $que_arr = json_last_error() || !is_array($que_arr) ? array((int)$que_id) : $que_arr;
        $queArr = empty($queId) ? array() : explode(",", $queId);
        if (empty($queArr)) {
            return array('code' => 407, 'message' => '技能组id为空');
        }
        //$user = $this->container->get("security.token_storage")->getToken()->getUser();
        //$winip = $this->container->getParameter("win_ip");
        $winIp = $this->container->get('icsoc_core.common.class')->newGetWinIp();
        //$win_ip = $user->getWinIp();
        $port = $this->container->getParameter('win_socket_port');
        $errorMsg = array();
        foreach ($queArr as $queId) {
            $queName = $this->dbal->fetchColumn(
                "SELECT que_name FROM win_queue WHERE id = :que_id",
                array('que_id' => $queId)
            );
            //验证技能组id 是否属于该企业；
            $msg = $this->container->get('icsoc_data.validator')->vccQue($vid, $queId, 403);
            if (!empty($msg)) {
                $errorMsg[] = array_merge($msg, array('que_id' => $queName));
                continue;
            }
            //验证技能组下是否有坐席；
            if (!$flag) {
                $count = $this->dbal->fetchColumn(
                    'SELECT count(*)
                    FROM win_agqu
                    WHERE que_id = :que_id ',
                    array('que_id' => $queId)
                );
                if (!empty($count)) {
                    $errorMsg[] = array('code' => 404, 'message' => '技能组下面有坐席', 'que_id' => $queName);
                    continue;
                }
            } else {
                //判断是否有坐席登陆
                $agCount = $this->dbal->fetchColumn(
                    "SELECT count(*) FROM win_agqu ag LEFT JOIN win_agent wa
                    ON wa.id = ag.ag_id WHERE ag.que_id = :que_id AND wa.ag_sta <> 0",
                    array('que_id' => $queId)
                );
                if ($agCount) {
                    $errorMsg[] = array('code' => 410, 'message' => '技能组下面有坐席登录', 'que_id' => $queName);
                    continue;
                }
            }
            $this->dbal->beginTransaction();
            try {
                $this->dbal->delete('win_agqu', array('que_id' => $queId));
                $this->dbal->update('win_queue', array('is_del' => 1), array('vcc_id' => $vid, 'id' => $queId));

                /** @var ActionLogger $actionLogger */
                $actionLogger = $this->container->get('icsoc_core.helper.logger');
                $logStr = $this->container->get('translator')
                    ->trans('Delete queue %str%', array('%str%' => implode(',', $queArr)));
                $actionLogger->actionLog(ActionLogger::ACTION_DELETE, $logStr);
//                //重载失败回滚；
//                if (!isset($ret['code']) || $ret['code'] != 200) {
//                    $this->dbal->rollBack();
//                    $errorMsg[] = array_merge($ret, array('que_id' => $queName));
//                } else {

                $this->dbal->commit();
                //删除技能组也需要重载技能组（需要在技能组删除成功后重载）
                $ret = $this->container->get('icsoc_data.validator')->wintelsReload($vid, $winIp, $port, 406);
                //重载失败；让他们自己手动重载；
                $data['que_id'] = $queId;
                $data['vcc_id'] = $vid;
                $this->writeMq(array('action'=>'delete', 'data'=>$data));
                if (!isset($ret['code']) || $ret['code'] != 200) {
                    $errorMsg[] = array_merge($ret, array('que_id' => $queName));
                } else {
                    $errorMsg[] = array('code' => 200, 'que_id' => $queName);
                }
                //}
            } catch (\Exception $e) {
                $this->dbal->rollBack();
                $errorMsg[] = array(
                    'code' => 405,
                    'message' => '删除技能组失败['.$e->getMessage().']',
                    'que_id' => $queName,
                );
            }
        }

        return array('code' => 500, 'message' => '总结果', 'data' => $errorMsg);
    }

    /**
     * 获取技能组列表
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         info,//提供搜素的字段有
     *                              //que_id: 技能组
     *                              //que_name :技能组名称
     *                     )
     * @return array
     */
    public function getList(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $info = empty($param['info']) ? '' : $this->purifyHtml($param['info']);
        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //分页搜索相关信息；
        $addInfo = array();
        if (!empty($info)) {
            $addInfo = json_decode($info, true);
            if (json_last_error()) {
                return array('code' => 404, 'message' => 'info格式非json');
            }
        }
        $where = '';
        if (isset($addInfo['filter'])) {
            if (isset($addInfo['filter']['que_id'])) {
                //验证技能组
                $msg = $this->container->get('icsoc_data.validator')->vccQue($vid, $addInfo['filter']['que_id'], 403);
                if (!empty($msg)) {
                    return $msg;
                }
            }
            $where = isset($addInfo['filter']['que_id']) && !empty($addInfo['filter']['que_id']) ?
                " AND w.id = '".(int) $addInfo['filter']['que_id']."'" : '';
            $where .= isset($addInfo['filter']['que_name']) && !empty($addInfo['filter']['que_name']) ?
                " AND que_name like '%".$addInfo['filter']['que_name']."%'" : '';
            if (isset($addInfo['filter']['keyword']) && !empty($addInfo['filter']['keyword'])) {
                $queKeyword = $addInfo['filter']['keyword'];
                $where .= " AND (que_name like '%".$queKeyword."%' OR que_num like '%".$queKeyword."%')";
            }
            $where .= isset($addInfo['filter']['que_ids']) && !empty($addInfo['filter']['que_ids']) ?
                " AND w.id in (".$addInfo['filter']['que_ids'].")" : '';
        }
        $count = $this->dbal->fetchColumn(
            'SELECT count(*)
            FROM win_queue as w
            WHERE vcc_id = :vcc_id AND is_del = 0 '.$where,
            array('vcc_id' => $vid)
        );
        $page = $this->container->get("icsoc_data.helper")->getPageInfo($count, 'win_queue', $addInfo);
        $page['sort'] = $page['sort'] != 1 ? 'w.'.$page['sort'] : $page['sort'];
        $list = $this->dbal->fetchAll(
            "SELECT que_name,que_tag,que_type,que_length,que_time,ring_time,next_wait,b_announce,noans_times,
            noans_wait,w.id,que_strategy,noans_action,wait_audio,s.name as sound_name,w.brecord,que_num,que_priority
            FROM win_queue as w LEFT JOIN win_sounds as s ON w.wait_audio = s.id
            WHERE w.vcc_id = :vcc_id AND w.is_del = 0 {$where}
            ORDER BY ".$page['sort'].' '.$page['order'].' LIMIT '.$page['start'].','.$page['limit'],
            array('vcc_id' => $vid)
        );
        $ret = array(
            'code' => 200,
            'message' => 'ok',
            'total' => $count,
            'totalPage' => $page['totalPage'],
            'data' => $list,
        );

        return $ret;
    }

    /**
     * 给技能组分配族系
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         que_id,//技能组id
     *                         agents=>//json格式 array(
     *                                               'ag_id'=>坐席id
     *                                               'skill'=>技能水平
     *                                             )
     *                     )
     * @return array
     */
    public function assignQueAgent(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queId = empty($param['que_id']) ? 0 : $param['que_id'];
        $agents = empty($param['agents']) ? 0 : $this->purifyHtml($param['agents']);

        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //验证技能组id 是否属于该企业；
        if (!empty($queId)) {
            $msg = $this->container->get('icsoc_data.validator')->vccQue($vid, $queId, 403);
            if (!empty($msg)) {
                return $msg;
            }
        } else {
            return array('code' => 404, 'message' => '技能组ID为空');
        }

        //验证agents 是否为空
        $msg = $this->container->get('icsoc_data.validator')->isEmptyName($agents, 409, 'agents参数为空');
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //验证agents
        $row = json_decode($agents, true);
        if (json_last_error()) {
            return array('code' => 405, 'message' => 'agents非JSON格式');
        }
        $errorMsg = array();
        $logStr = "";
        foreach ($row as $v) {
            if (isset($v['ag_id']) && isset($v['skill'])) {
                //先判断ag_id 是否属于该企业；
                $count = $this->dbal->fetchColumn(
                    'SELECT count(*)
                    FROM win_agent
                    WHERE vcc_id = :vcc_id AND id = :ag_id AND is_del = 0',
                    array('vcc_id' => $vid, 'ag_id' => $v['ag_id'])
                );
                if (!$count) {
                    $errorMsg[] = array(
                        'code' => '406',
                        'message' => 'ag_id 不属于该企业',
                        'data' => $v,
                    );
                    continue;
                }

                //再判断该坐席是否分配了
                $total = $this->dbal->fetchColumn(
                    'SELECT count(*)
                    FROM win_agqu
                    WHERE que_id = :que_id AND ag_id = :ag_id ',
                    array('que_id' => $queId, 'ag_id' => $v['ag_id'])
                );

                if ($total) {
                    $errorMsg[] = array(
                        'code' => '407',
                        'message' => '坐席已经分配技能组',
                        'data' => $v,
                    );
                    continue;
                }
                //写入到数据库 默认给技能水平
                $data = array('que_id' => $queId, 'ag_id' => $v['ag_id'], 'skill' => $v['skill']);
                try {
                    $this->dbal->insert('win_agqu', $data);
                    $logStr .= "[ag_id:".$v['ag_id'].",que_id:$queId] ";
                    $errorMsg[] = array('code' => '200', 'message' => 'ok', 'data' => $v);
                } catch (\Exception $e) {
                    $errorMsg[] = array(
                        'code' => '408',
                        'message' => '分配失败 ['.$e->getMessage().']',
                    );
                }
            }
        }
        if (!empty($logStr)) {
            /** @var ActionLogger $actionLogger */
            $actionLogger = $this->container->get('icsoc_core.helper.logger');
            $logStr = $this->container->get('translator')
                ->trans('Skill group assignment %str%', array('%str%' => $logStr));
            $actionLogger->actionLog(ActionLogger::ACTION_ADD, $logStr);
        }
        //总结果
        $ret = array(
            'code' => '500',
            'message' => '总结果',
            'data' => $errorMsg,
        );

        return $ret;
    }

    /**
     * 给技能组分配取消
     * @param array $param 参数，格式为
     *                     array(
     *                         vcc_code,//企业代码
     *                         que_id,//技能组id
     *                         agents=>//json格式 array(
     *                                               'ag_id'=>坐席id
     *                                               'skill'=>技能水平
     *                                             )
     *                     )
     * @return array
     */
    public function cancelAssign(array $param = array())
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queId = empty($param['que_id']) ? 0 : $param['que_id'];
        $agents = empty($param['agents']) ? 0 : $param['agents'];

        $msg = $vid = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //验证技能组id 是否属于该企业；
        if (!empty($queId)) {
            $msg = $this->container->get('icsoc_data.validator')->vccQue($vid, $queId, 403);
            if (!empty($msg)) {
                return $msg;
            }
        } else {
            $ret = array('code' => 404, 'message' => '技能组ID为空');

            return $ret;
        }

        //验证agents 是否为空
        $msg = $this->container->get('icsoc_data.validator')->isEmptyName($agents, 405, 'agents参数为空');
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //验证agents
        $row = json_decode($agents, true);
        if (json_last_error()) {
            $ret = array('code' => 406, 'message' => 'agents非JSON格式');

            return $ret;
        }
        is_array($row) ? array_push($row, 0) : $row = array(0);
        //删除
        $temp = array();
        foreach ($row as $v) {
            $temp[] = (int) $v;
        }
        $temp = array_unique($temp);
        $agents = implode(',', $temp);
        $this->dbal->executeQuery(
            "DELETE FROM win_agqu WHERE que_id = :que_id AND ag_id IN ($agents)",
            array('que_id' => $queId)
        );

        return array('code' => 200, 'message' => 'ok');
    }

    /**
     * 获取以技能组id为键，技能组名称为值的数组
     * @param int  $vccId
     * @param bool $isVerify     是否验证权限 false不验证,true验证
     * @param bool $isCheckAgent 是否验证是坐席权限（为了区分技能组话务报表和各个报表展示技能组方式不一样）
     * @return array|bool 失败返回false，成功返回数组
     */
    public function getQueueNameKeyedByIdArray($vccId, $isVerify = false, $isCheckAgent = false)
    {
        if (empty($vccId)) {
            return false;
        }

        /** @var \Doctrine\DBAL\Connection $conn */
        $conn = $this->container->get("doctrine.dbal.default_connection");
        $query = $conn->fetchAll(
            "SELECT id,que_name,que_num FROM win_queue WHERE is_del=0 AND vcc_id=:vcc_id",
            array(':vcc_id' => $vccId)
        );

        /** @var array $authority 数据权限 */
        $authority = array();

        if (!empty($isVerify)) {
            $authority = $this->container->get("icsoc_core.common.class")->getUserTypeCondition();
        }

        $queues = array();

        foreach ($query as $row) {
            if (!empty($row['que_num'])) {
                $row['que_name'] .= '['.$row['que_num'].']';
            }

            if (!empty($isVerify) && isset($authority['get_que_ids']) && !$isCheckAgent) {
                if (in_array($row['id'], $authority['get_que_ids'])) {
                    $queues[$row['id']] = $row['que_name'];
                }
            } elseif (!empty($isVerify) && isset($authority['que_id']) && $isCheckAgent) {
                //这个给技能组话务报表
                if (in_array($row['id'], $authority['que_id'])) {
                    $queues[$row['id']] = $row['que_name'];
                }
            } else {
                $queues[$row['id']] = $row['que_name'];
            }
        }

        return $queues;
    }

    /**
     * 操作快捷分配；
     * @param array $param
     * @return array|string
     */
    public function actionFastAssignAgent($param)
    {
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $queId = empty($param['que_id']) ? 0 : $param['que_id'];
        $agents = empty($param['ids']) ? array() : $param['ids'];
        $actionFlag = empty($param['flag']) ? 1 : $param['flag']; //操作类型 1,插入，2,取消
        //$user = $this->container->get("security.token_storage")->getToken()->getUser();
        $msg = $vccId = $this->container->get('icsoc_data.validator')->checkVccCode($vccCode);
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }

        //验证技能组id 是否属于该企业；
        if (!empty($queId)) {
            $msg = $this->container->get('icsoc_data.validator')->vccQue($vccId, $queId, 403);
            if (!empty($msg)) {
                return $msg;
            }
        } else {
            $ret = array('code' => 404, 'message' => '技能组ID为空');

            return $ret;
        }
        //验证agents 是否为空
        $msg = $this->container->get('icsoc_data.validator')->isEmptyName($agents, 405, 'agents参数为空');
        if (!empty($msg) && is_array($msg)) {
            return $msg;
        }
        $address = $this->container->get('icsoc_core.common.class')->newGetWinIp();
        //$address = $user->getWinIp();
        $port = $this->container->getParameter('win_socket_port');
        foreach ($agents as $v) {
            //$this->dbal->beginTransaction();
            if ($actionFlag == 1) {
                $count = $this->dbal
                    ->fetchColumn("SELECT count(*) FROM win_agqu WHERE que_id=:que_id AND ag_id=:ag_id", array(
                        'ag_id' => $v, 'que_id' => $queId,
                    ));
                if (!$count) {
                    $this->dbal->insert('win_agqu', array('que_id' => $queId, 'ag_id' => $v));
                }
            } else {
                $this->dbal->delete('win_agqu', array('que_id' => $queId, 'ag_id' => $v));
            }
            //重载坐席
            $resMeesg = $this->container->get('icsoc_data.validator')->reloadAgent($vccId, $address, $v, $port);
            if (isset($resMeesg['code']) && $resMeesg['code'] != 200 && (isset($resMeesg['fail']) && $resMeesg['fail'])) {
                //$this->dbal->rollBack();
                $agNum = $this->dbal->fetchColumn("SELECT ag_num FROM win_agent WHERE id = :id", array('id' => $v));
                $message[] = $agNum;
            } else {
                //$this->dbal->commit();
            }
        }
        if (empty($message)) {
            return array("code" => '200', "message" => 'ok');
        } else {
            $str = $this->container->get('translator')->trans('Agent number')."[".implode(',', $message)."]";
            $str .= $this->container->get('translator')->trans('Skill set overload failure');

            return array("code" => 500, "message" => $str);
        }
    }

    /**
     * 批量添加技能组(添加技能组同时把要绑定的坐席、分机同时创建，然后要需静态登录相应坐席)
     * @param array $param
     *        array(
     *                         vcc_id,//企业id
     *                         vcc_code,//企业代码
     *                         role = array([name]=>[roleId]),
     *                         [0]=>array(
     *                             if_login,
     *                             queue = array(
     *                                  que_name,
     *                                  que_num,
     *                                  que_type,
     *                                  que_time,
     *                                  ring_time,
     *                                  next_wait,
     *                                  b_announce,
     *                                  tellevel,
     *                                  que_priority
     *                              )
     *                              agent = array(
     *                                  phone
     *                                  skill
     *                                  role
     *                              )
     *                           )
     *                        )
     *                     )
     *
     * @return array
     */
    public function batchAddQueue($param)
    {
        //$user = $this->container->get("security.token_storage")->getToken()->getUser();
        //$winip = $this->container->getParameter("win_ip");
        $winIp = $this->container->get('icsoc_core.common.class')->newGetWinIp();
        //$win_ip = $user->getWinIp();
        $port = $this->container->getParameter('win_socket_port');
        $queNames = '';
        $vccCode = empty($param['vcc_code']) ? 0 : $param['vcc_code'];
        $vccId = empty($param['vcc_id']) ? 0 : $param['vcc_id'];
        $roles = empty($param['role']) ? array() : $param['role'];
        unset($param['vcc_code']);
        unset($param['vcc_id']);
        unset($param['role']);

        $this->dbal->beginTransaction();
        try {
            $staticLoginInfo = array();//静态登录信息
            //默认和其它技能组一样；
            $tellevel = $this->dbal->fetchColumn(
                "SELECT tellevel FROM win_queue WHERE vcc_id = ? AND is_del = 0 LIMIT 1",
                array($vccId)
            );
            $autoEvaluate = $tellevel & 64;
            foreach ($param as $in) {
                //2、插入技能组
                if (isset($in['queue']) && (!empty($in['queue']))) {
                    /*$in['queue']['que_name'] = $this->container->get("icsoc_core.export.csv")
                        ->convertCharset($in['queue']['que_name'], "GB2312", "UTF-8");*/
                    $queNames .= "【".$in['queue']['que_name']."】";
                    $in['queue']['vcc_id'] = $vccId;
                    $in['queue']['que_strategy'] = 2;//默认分配策略是技能组高优先
                    $in['queue']['brecord'] = 1;//默认是否录音是
                    $in['queue']['que_length'] = 5;//默认最大排队数是5
                    $in['queue']['noans_action'] = 0;//默认无应答操作是不处理
                    $in['queue']['noans_times'] = 3;//默认无应答次数3
                    $in['queue']['noans_wait'] = 10;//默认无应答等待时长10
                    if ($in['queue']['tellevel'] == 'Y') {
                        @$in['queue']['tellevel'] = tellevel | 0x20;
                    } else {
                        @$in['queue']['tellevel'] = tellevel & ~0x20;
                    }

                    $tellevel = empty($autoEvaluate) ? $in['queue']['tellevel'] & ~0x40 : $in['queue']['tellevel'] | 0x40;
                    $in['queue']['tellevel'] = $tellevel;
                    $this->dbal->insert('win_queue', $in['queue']);
                    //插入队列
                    $queId = $this->dbal->lastInsertId();
                    $Mqdata['que_id'] = $queId;
                    $Mqdata['vcc_id'] = $vccId;
                    $Mqdata['que_name'] = $in['queue']['que_name'];
                    $Mqdata['que_type'] = $in['queue']['que_type'];
                    $this->writeMq(array('action'=>'create', 'data'=>$Mqdata));
                    $queId = $this->dbal->lastInsertId();

                    if (isset($in['if_login']) && (!empty($in['if_login']))) {
                        //3、插入用户
                        if (isset($in['agent']) && (!empty($in['agent']))) {
                            //查看最大坐席数
                            $agents = $this->dbal->fetchColumn(
                                "SELECT agents
                                     FROM cc_ccods
                                     WHERE vcc_id = :vcc_id ",
                                array('vcc_id' => $vccId)
                            );
                            $alreay = $this->dbal->fetchColumn(
                                "SELECT count(*)
                                     FROM win_agent
                                     WHERE vcc_id = :vcc_id AND ag_role <> -1 AND is_del = 0",
                                array('vcc_id' => $vccId)
                            );
                            if ($alreay >= $agents || $alreay + count($in['agent']) > $agents) {
                                return array(
                                    'error' => 1,
                                    'message' => '坐席已经数量将超过极限',
                                );
                            }
                            foreach ($in['agent'] as $k => $agent) {
                                //角色
                                $newRoleName = $this->container->get("icsoc_core.export.csv")
                                    ->convertCharset(trim($agent['role']), "GB2312", "UTF-8");
                                if (empty($newRoleName)) {
                                    continue;
                                }
                                if (isset($roles[$newRoleName])) {
                                    $useRole = $roles[$newRoleName];
                                } else {
                                    $roleInfo = array(
                                        'vcc_id' => $vccId,
                                        'name' => $newRoleName,
                                        'role_grade' => 3,
                                    );
                                    $this->dbal->insert('cc_roles', $roleInfo);
                                    $useRole = $this->dbal->lastInsertId();
                                    $roles[$newRoleName] = $useRole;
                                }

                                //用户信息整理、插入
                                $agName = $agNum = $in['queue']['que_num'].($k + 1);//坐席工号
                                $agentInfo = array(
                                    'vcc_id' => $vccId,
                                    'vcc_code' => $vccCode,
                                    'ag_num' => $agNum,
                                    'ag_name' => $agName,
                                    'ag_password' => md5('123456'),
                                    'user_role' => $useRole,
                                    'user_type' => 1,
                                    'user_queues' => $queId,
                                    'crm_datarole' => 1,
                                );
                                $this->dbal->insert('win_agent', $agentInfo);
                                //插入队列
                                $agId = $this->dbal->lastInsertId();
                                $agentInfo['ag_id'] = $agId;
                                $this->container->get('icsoc_data.model.agent')->writeMq(array('action'=>'create', 'data'=>$agentInfo));
                                unset($agentInfo['ag_id']);

                                //插入用户相应技能水平
                                $this->dbal->insert('win_agqu', array('que_id' => $queId, 'ag_id' => $agId, 'skill' => $agent['skill']));

                                //分机
                                $phoneInfo = array(
                                    'vcc_id' => $vccId,
                                    'vcc_code' => $vccCode,
                                    'pho_num' => $agent['phone'],
                                    'pho_type' => 1,
                                );
                                $isExistPhone = $this->dbal->fetchColumn(
                                    "SELECT count(*) FROM win_phone WHERE vcc_id = ? AND pho_num = ?",
                                    array($vccId, $agent['phone'])
                                );
                                if (empty($isExistPhone)) {
                                    $this->dbal->insert('win_phone', $phoneInfo);
                                }
                                //整理静态登录信息
                                if ($in['if_login'] == 'Y') {
                                    $staticLoginInfo[] = array('ag_num' => $agNum, 'phone' => $agent['phone']);
                                }
                            }
                        }

                    }
                }
            }

            $this->dbal->commit();

            //添加技能组成功之后；重载技能组；
            $ret = $this->container->get('icsoc_data.validator')->wintelsReload($vccId, $winIp, $port, 406);
            /** @var ActionLogger $actionLogger */
            $actionLogger = $this->container->get('icsoc_core.helper.logger');
            $logStr = $this->container->get('translator')->trans('Add queue %str%', array('%str%' => $queNames));
            $actionLogger->actionLog(ActionLogger::ACTION_ADD, $logStr);
            if (isset($ret['code']) && $ret['code'] == 200) {
                if (!empty($staticLoginInfo)) {
                    //坐席静态登录
                    $params = array('vcc_id' => $vccId, 'vcc_code' => $vccCode, 'data' => $staticLoginInfo);
                    $result = $this->container->get("icsoc_data.model.agent")->staticAgentLogin($params);
                    if (isset($result['code']) && $result['code'] == 200) {
                        $ret = array(
                            'code' => 200,
                            'message' => 'ok',
                        );
                    } else {
                        $str = isset($result['errors'][0]['message']) ? $result['errors'][0]['message'] : $result['message'];
                        $ret = array(
                            'error' => 1,
                            'message' => '批量导入技能组成功，静态登录失败['.$str.']',
                        );
                    }
                } else {
                    $ret = array(
                        'code' => 200,
                        'message' => 'ok',
                    );
                }
            } else {
                $ret = array(
                    'error' => 1,
                    'message' => '批量导入技能组成功,技能组重载失败',
                );
            }

            return $ret;
        } catch (\Exception $e) {
            $this->dbal->rollBack();
            $ret = array(
                'code' => 414,
                'message' => '批量导入技能组失败['.$e->getMessage().']',
            );

            return $ret;
        }
    }

    /**
     * 把消息写入到队列
     *
     * @param array $data
     */
    public function writeMq($data)
    {
        $producer = $this->container->get('old_sound_rabbit_mq.agent_producer_producer');
        $producer->setContentType('application/json');
        $producer->publish(json_encode($data), 'manage.queue');
    }
}
